﻿#include "GameWnd.h"
#include <QMessageBox>
#include <QMouseEvent>
#include <QPainter>

GameWnd::GameWnd(QWidget *parent) : QFrame(parent)
{
	setMinimumSize((CHESS_COLUMES + 1)*RECT_WIDTH, (CHESS_ROWS + 1)*RECT_HEIGHT);

    mPos = QPoint(-1,-1);
    mBlack = true;

    mClient = new Client;
    connect(mClient, &Client::sigOtherUserMove,this, &GameWnd::slotOtherUserMove);
    connect(mClient, &Client::sigNewGame,this, &GameWnd::slotNewGame);

    //转发信号，给MainWindow处理
    connect(mClient, &Client::sigOutput,this, &GameWnd::sigOutput);
    connect(mClient, &Client::sigUpdateRoomState,this, &GameWnd::sigUpdateRoomState);
}

GameWnd::~GameWnd()
{

}

void GameWnd::Connect(QString ip, int port, int room)
{
    mClient->ConnectToServer(ip, port, room);
}

void GameWnd::Say(QString text)
{
    mClient->SendMsg_Say(text);
}

void GameWnd::Output(QString text)
{
    emit sigOutput(text);
}

void GameWnd::GetRoomState(QList<ROOM_STATE> &state)
{
    mClient->GetRoomState(state);
}

void GameWnd::slotNewGame()
{
    mItems.clear();
    mPos = QPoint(-1,-1);
    mBlack = true;
}

void GameWnd::paintEvent(QPaintEvent *e)
{
    DrawChessboard();
    DrawItems();
    DrawItemWithMouse();

    update();
}

void GameWnd::DrawChessboard()
{
    QPainter painter(this);


    painter.setPen(QPen(QColor(Qt::black),2));

    for(int i = 0;i<CHESS_COLUMES; i++)
    {
        for (int j = 0; j<CHESS_ROWS; j++)
        {
            painter.drawRect( (i+0.5)*RECT_WIDTH,(j+0.5)*RECT_HEIGHT,RECT_WIDTH,RECT_HEIGHT);
        }
    }
}

void GameWnd::DrawItems()
{
    QPainter painter(this);
    painter.setPen(QPen(QColor(Qt::transparent)));

    for (int i = 0; i<mItems.size(); i++)
    {
        Item item = mItems[i];
        if(item.mPt == mPos)
        {
            painter.setPen(QPen(QColor("#ff3333"),2,Qt::SolidLine));
            if (item.mBlack)
            {
                painter.setBrush(Qt::black);
            }
            else
            {
                painter.setBrush(Qt::white);
            }
            DrawChessAtPoint(painter,item.mPt);
            painter.setPen(QPen(QColor(Qt::transparent)));
            continue;
        }
        if (item.mBlack)
        {
            painter.setBrush(Qt::black);
        }
        else
        {
            painter.setBrush(Qt::white);
        }
        DrawChessAtPoint(painter,item.mPt);
    }
}

void GameWnd::DrawChessAtPoint(QPainter& painter,QPoint& pt)
{
    QPoint ptCenter((pt.x()+0.5)*RECT_WIDTH,(pt.y()+0.5)*RECT_HEIGHT);
    painter.drawEllipse(ptCenter,RECT_WIDTH / 2,RECT_HEIGHT / 2);
}

void GameWnd::DrawItemWithMouse()
{
    QPainter painter(this);
    painter.setPen(QPen(QColor(Qt::transparent)));

    if (mClient->IsBlack())
    {
        painter.setBrush(Qt::black);
    }
    else
    {
        painter.setBrush(Qt::white);
    }

    painter.drawEllipse(mapFromGlobal(QCursor::pos()),RECT_WIDTH / 2,RECT_HEIGHT / 2);

}

void GameWnd::mousePressEvent(QMouseEvent * e)
{
    if (mClient->IsBlack())
    {
        if (!mBlack)
        {
            return;
        }
    }
    else
    {
        if (mBlack)
        {
            return;
        }
    }

    QPoint pt;
    pt.setX( (e->pos().x() ) / RECT_WIDTH);
    pt.setY( (e->pos().y() ) / RECT_HEIGHT);

    for (int i = 0; i<mItems.size(); i++)
    {
        Item item = mItems[i];
        if (item.mPt == pt)
        {
            //已有棋子
            return;
        }
    }
    mPos = pt;
    mClient->SendMsg_Move(pt.x(),pt.y());

    Item item(pt,mBlack);
    mItems.append(item);

    int nLeft =			CountNearItem(item,QPoint(-1,0));
    int nLeftUp =		CountNearItem(item,QPoint(-1,-1));
    int nUp =			CountNearItem(item,QPoint(0,-1));
    int nRightUp =		CountNearItem(item,QPoint(1,-1));
    int nRight =		CountNearItem(item,QPoint(1,0));
    int nRightDown =	CountNearItem(item,QPoint(1,1));
    int nDown =			CountNearItem(item,QPoint(0,1));
    int nLeftDown =		CountNearItem(item,QPoint(-1,1));
    if ( (nLeft + nRight) >= 4 ||
         (nLeftUp + nRightDown) >= 4 ||
         (nUp + nDown) >= 4 ||
         (nRightUp + nLeftDown) >= 4 )
    {
        if (mBlack == mClient->IsBlack())
        {
            //赢的一方通知服务器自己赢了
            mClient->SendMsg_Success();
        }

        QString str = mBlack? QStringLiteral("黑棋胜利！") : QStringLiteral("白棋胜利！");
        QMessageBox::information(this, QStringLiteral("游戏结束"),str, QMessageBox::Yes , QMessageBox::Yes);
        mItems.clear();
        //NewGame();
        return;
    }
    mBlack = !mBlack;
}

int GameWnd::CountNearItem(Item item,QPoint ptDirection)
{
    int nCount = 0;
    item.mPt += ptDirection;

    while (mItems.contains(item))
    {
        nCount++;
        item.mPt += ptDirection;
    }
    return nCount;
}

void GameWnd::slotOtherUserMove( int x,int y )
{
    mPos = QPoint(x,y);

    QPoint pt(x,y);
    Item item(pt,mBlack);
    mItems.append(item);

    int nLeft =			CountNearItem(item,QPoint(-1,0));
    int nLeftUp =		CountNearItem(item,QPoint(-1,-1));
    int nUp =			CountNearItem(item,QPoint(0,-1));
    int nRightUp =		CountNearItem(item,QPoint(1,-1));
    int nRight =		CountNearItem(item,QPoint(1,0));
    int nRightDown =	CountNearItem(item,QPoint(1,1));
    int nDown =			CountNearItem(item,QPoint(0,1));
    int nLeftDown =		CountNearItem(item,QPoint(-1,1));
    if ( (nLeft + nRight) >= 4 ||
        (nLeftUp + nRightDown) >= 4 ||
        (nUp + nDown) >= 4 ||
        (nRightUp + nLeftDown) >= 4 )
    {
        QString str = mBlack? QStringLiteral("黑棋胜利！") : QStringLiteral("白棋胜利！");
        QMessageBox::information(NULL, QStringLiteral("游戏结束"),str, QMessageBox::Yes , QMessageBox::Yes);

        mItems.clear();
        //NewGame();
        return;
    }


    mBlack = !mBlack;
    update();
}
